package main

import (
	"fmt"

	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

/**
假设你已经使用Sqlx连接到一个数据库，并且有一个 employees 表，
包含字段 id 、 name 、 department 、 salary 。

- 编写Go代码，使用Sqlx查询 employees 表中所有部门为 "技术部" 的员工信息，并将结果映射到一个自定义的 Employee 结构体切片中。,
- 编写Go代码，使用Sqlx查询 employees 表中工资最高的员工信息，并将结果映射到一个 Employee 结构体中。
*/

/**
假设有一个 books 表，包含字段 id 、 title 、 author 、 price 。

- 定义一个 Book 结构体，包含与 books 表对应的字段。,
- 编写Go代码，使用Sqlx执行一个复杂的查询，例如查询价格大于 50 元的书籍，并将结果映射到 Book 结构体切片中，确保类型安全。
*/

var Db *sqlx.DB

type Employee struct {
	ID         uint `gorm:"primary_key" db:"id"`
	Name       string
	Department string
	Salary     float64
}

type Book struct {
	Id     uint `gorm:"primary_key" db:"id"`
	Title  string
	Author string
	Price  float64
}

func init() {
	database, err := sqlx.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/sqlx")
	if err != nil {
		fmt.Println("open database error:", err)
		panic(err)
	}
	Db = database
}

func main() {
	//insertEmployee(&Employee{Name: "John", Salary: 5000.00, Department: "Sales"})
	//insertEmployee(&Employee{Name: "Jane", Salary: 4000.00, Department: "Tech"})
	//insertEmployee(&Employee{Name: "Romio", Salary: 3000.00, Department: "Service"})

	//查询所有部门为 "技术部" 的员工信息，并将结果映射到一个自定义的 Employee 结构体切片中。
	//emps := []Employee{}
	//err := Db.Select(&emps, "SELECT * FROM employees where department = ?  ORDER BY id DESC", "Tech")
	//if err != nil {
	//	panic(err)
	//}
	//fmt.Println(emps)
	//
	////查询表中工资最高的员工信息，并将结果映射到一个 Employee 结构体中。
	//var emp Employee
	//err2 := Db.Get(&emp, "select * from employees order by salary desc limit 1")
	//if err2 != nil {
	//	panic(err2)
	//}
	//fmt.Println(emp)

	//insertBook(&Book{Title: "西游记", Author: "吴承恩", Price: 100})
	//insertBook(&Book{Title: "红楼梦", Author: "曹雪芹", Price: 80})
	//insertBook(&Book{Title: "水浒传", Author: "施耐庵", Price: 70})
	//insertBook(&Book{Title: "三国演义", Author: "罗贯中", Price: 90})
	//查询价格大于 50 元的书籍，并将结果映射到 Book 结构体切片中，确保类型安全。
	var books []Book
	err := Db.Select(&books, "select * from book where price > 70")
	if err != nil {
		panic(err)
	}
	fmt.Println(books)

}

func insertBook(b *Book) uint {

	r, err := Db.Exec("INSERT INTO `book` (`title`, `author`, `price`) VALUES (?, ?, ?)", b.Title, b.Author, b.Price)
	if err != nil {
		fmt.Println("exec failed:", err)
		return 0
	}
	id, err := r.LastInsertId()
	if err != nil {
		fmt.Println("exec failed:", err)
		return 0
	}
	fmt.Println("insert id:", id)
	b.Id = uint(id)
	return b.Id
}

func insertEmployee(emp *Employee) uint {
	r, err := Db.Exec("INSERT INTO `employees` (`name`, `department`, `salary`) VALUES (?, ?, ?)", emp.Name, emp.Department, emp.Salary)
	if err != nil {
		fmt.Println("exec failed:", err)
		return 0
	}
	id, err := r.LastInsertId()
	if err != nil {
		fmt.Println("exec failed:", err)
		return 0
	}
	fmt.Println("insert id:", id)
	emp.ID = uint(id)
	return emp.ID
}
